package com.squeekeek.util.qrcode;

public class QRErrorCorrection {
	private static final byte EC_L = 0x00;
	private static final byte EC_M = 0x01;
	private static final byte EC_Q = 0x02;
	private static final byte EC_H = 0x03;
	
	// Some handy generated lookup tables
	// Exponent of primitive element a = 1
	private static byte[] primitiveElmsExp = {
		(byte) 0x01 ,  (byte) 0x02 ,  (byte) 0x04 ,  (byte) 0x08 ,  (byte) 0x10 ,  (byte) 0x20 ,  (byte) 0x40 ,  (byte) 0x80 ,
		(byte) 0x1d ,  (byte) 0x3a ,  (byte) 0x74 ,  (byte) 0xe8 ,  (byte) 0xcd ,  (byte) 0x87 ,  (byte) 0x13 ,  (byte) 0x26 ,
		(byte) 0x4c ,  (byte) 0x98 ,  (byte) 0x2d ,  (byte) 0x5a ,  (byte) 0xb4 ,  (byte) 0x75 ,  (byte) 0xea ,  (byte) 0xc9 ,
		(byte) 0x8f ,  (byte) 0x03 ,  (byte) 0x06 ,  (byte) 0x0c ,  (byte) 0x18 ,  (byte) 0x30 ,  (byte) 0x60 ,  (byte) 0xc0 ,
		(byte) 0x9d ,  (byte) 0x27 ,  (byte) 0x4e ,  (byte) 0x9c ,  (byte) 0x25 ,  (byte) 0x4a ,  (byte) 0x94 ,  (byte) 0x35 ,
		(byte) 0x6a ,  (byte) 0xd4 ,  (byte) 0xb5 ,  (byte) 0x77 ,  (byte) 0xee ,  (byte) 0xc1 ,  (byte) 0x9f ,  (byte) 0x23 ,
		(byte) 0x46 ,  (byte) 0x8c ,  (byte) 0x05 ,  (byte) 0x0a ,  (byte) 0x14 ,  (byte) 0x28 ,  (byte) 0x50 ,  (byte) 0xa0 ,
		(byte) 0x5d ,  (byte) 0xba ,  (byte) 0x69 ,  (byte) 0xd2 ,  (byte) 0xb9 ,  (byte) 0x6f ,  (byte) 0xde ,  (byte) 0xa1 ,
		(byte) 0x5f ,  (byte) 0xbe ,  (byte) 0x61 ,  (byte) 0xc2 ,  (byte) 0x99 ,  (byte) 0x2f ,  (byte) 0x5e ,  (byte) 0xbc ,
		(byte) 0x65 ,  (byte) 0xca ,  (byte) 0x89 ,  (byte) 0x0f ,  (byte) 0x1e ,  (byte) 0x3c ,  (byte) 0x78 ,  (byte) 0xf0 ,
		(byte) 0xfd ,  (byte) 0xe7 ,  (byte) 0xd3 ,  (byte) 0xbb ,  (byte) 0x6b ,  (byte) 0xd6 ,  (byte) 0xb1 ,  (byte) 0x7f ,
		(byte) 0xfe ,  (byte) 0xe1 ,  (byte) 0xdf ,  (byte) 0xa3 ,  (byte) 0x5b ,  (byte) 0xb6 ,  (byte) 0x71 ,  (byte) 0xe2 ,
		(byte) 0xd9 ,  (byte) 0xaf ,  (byte) 0x43 ,  (byte) 0x86 ,  (byte) 0x11 ,  (byte) 0x22 ,  (byte) 0x44 ,  (byte) 0x88 ,
		(byte) 0x0d ,  (byte) 0x1a ,  (byte) 0x34 ,  (byte) 0x68 ,  (byte) 0xd0 ,  (byte) 0xbd ,  (byte) 0x67 ,  (byte) 0xce ,
		(byte) 0x81 ,  (byte) 0x1f ,  (byte) 0x3e ,  (byte) 0x7c ,  (byte) 0xf8 ,  (byte) 0xed ,  (byte) 0xc7 ,  (byte) 0x93 ,
		(byte) 0x3b ,  (byte) 0x76 ,  (byte) 0xec ,  (byte) 0xc5 ,  (byte) 0x97 ,  (byte) 0x33 ,  (byte) 0x66 ,  (byte) 0xcc ,
		(byte) 0x85 ,  (byte) 0x17 ,  (byte) 0x2e ,  (byte) 0x5c ,  (byte) 0xb8 ,  (byte) 0x6d ,  (byte) 0xda ,  (byte) 0xa9 ,
		(byte) 0x4f ,  (byte) 0x9e ,  (byte) 0x21 ,  (byte) 0x42 ,  (byte) 0x84 ,  (byte) 0x15 ,  (byte) 0x2a ,  (byte) 0x54 ,
		(byte) 0xa8 ,  (byte) 0x4d ,  (byte) 0x9a ,  (byte) 0x29 ,  (byte) 0x52 ,  (byte) 0xa4 ,  (byte) 0x55 ,  (byte) 0xaa ,
		(byte) 0x49 ,  (byte) 0x92 ,  (byte) 0x39 ,  (byte) 0x72 ,  (byte) 0xe4 ,  (byte) 0xd5 ,  (byte) 0xb7 ,  (byte) 0x73 ,
		(byte) 0xe6 ,  (byte) 0xd1 ,  (byte) 0xbf ,  (byte) 0x63 ,  (byte) 0xc6 ,  (byte) 0x91 ,  (byte) 0x3f ,  (byte) 0x7e ,
		(byte) 0xfc ,  (byte) 0xe5 ,  (byte) 0xd7 ,  (byte) 0xb3 ,  (byte) 0x7b ,  (byte) 0xf6 ,  (byte) 0xf1 ,  (byte) 0xff ,
		(byte) 0xe3 ,  (byte) 0xdb ,  (byte) 0xab ,  (byte) 0x4b ,  (byte) 0x96 ,  (byte) 0x31 ,  (byte) 0x62 ,  (byte) 0xc4 ,
		(byte) 0x95 ,  (byte) 0x37 ,  (byte) 0x6e ,  (byte) 0xdc ,  (byte) 0xa5 ,  (byte) 0x57 ,  (byte) 0xae ,  (byte) 0x41 ,
		(byte) 0x82 ,  (byte) 0x19 ,  (byte) 0x32 ,  (byte) 0x64 ,  (byte) 0xc8 ,  (byte) 0x8d ,  (byte) 0x07 ,  (byte) 0x0e ,
		(byte) 0x1c ,  (byte) 0x38 ,  (byte) 0x70 ,  (byte) 0xe0 ,  (byte) 0xdd ,  (byte) 0xa7 ,  (byte) 0x53 ,  (byte) 0xa6 ,
		(byte) 0x51 ,  (byte) 0xa2 ,  (byte) 0x59 ,  (byte) 0xb2 ,  (byte) 0x79 ,  (byte) 0xf2 ,  (byte) 0xf9 ,  (byte) 0xef ,
		(byte) 0xc3 ,  (byte) 0x9b ,  (byte) 0x2b ,  (byte) 0x56 ,  (byte) 0xac ,  (byte) 0x45 ,  (byte) 0x8a ,  (byte) 0x09 ,
		(byte) 0x12 ,  (byte) 0x24 ,  (byte) 0x48 ,  (byte) 0x90 ,  (byte) 0x3d ,  (byte) 0x7a ,  (byte) 0xf4 ,  (byte) 0xf5 ,
		(byte) 0xf7 ,  (byte) 0xf3 ,  (byte) 0xfb ,  (byte) 0xeb ,  (byte) 0xcb ,  (byte) 0x8b ,  (byte) 0x0b ,  (byte) 0x16 ,
		(byte) 0x2c ,  (byte) 0x58 ,  (byte) 0xb0 ,  (byte) 0x7d ,  (byte) 0xfa ,  (byte) 0xe9 ,  (byte) 0xcf ,  (byte) 0x83 ,
		(byte) 0x1b ,  (byte) 0x36 ,  (byte) 0x6c ,  (byte) 0xd8 ,  (byte) 0xad ,  (byte) 0x47 ,  (byte) 0x8e ,  (byte) 0x01 ,
		(byte) 0x02 ,  (byte) 0x04 ,  (byte) 0x08 ,  (byte) 0x10 ,  (byte) 0x20 ,  (byte) 0x40 ,  (byte) 0x80 ,  (byte) 0x1d ,
		(byte) 0x3a ,  (byte) 0x74 ,  (byte) 0xe8 ,  (byte) 0xcd ,  (byte) 0x87 ,  (byte) 0x13 ,  (byte) 0x26 ,  (byte) 0x4c ,
		(byte) 0x98 ,  (byte) 0x2d ,  (byte) 0x5a ,  (byte) 0xb4 ,  (byte) 0x75 ,  (byte) 0xea ,  (byte) 0xc9 ,  (byte) 0x8f ,
		(byte) 0x03 ,  (byte) 0x06 ,  (byte) 0x0c ,  (byte) 0x18 ,  (byte) 0x30 ,  (byte) 0x60 ,  (byte) 0xc0 ,  (byte) 0x9d ,
		(byte) 0x27 ,  (byte) 0x4e ,  (byte) 0x9c ,  (byte) 0x25 ,  (byte) 0x4a ,  (byte) 0x94 ,  (byte) 0x35 ,  (byte) 0x6a ,
		(byte) 0xd4 ,  (byte) 0xb5 ,  (byte) 0x77 ,  (byte) 0xee ,  (byte) 0xc1 ,  (byte) 0x9f ,  (byte) 0x23 ,  (byte) 0x46 ,
		(byte) 0x8c ,  (byte) 0x05 ,  (byte) 0x0a ,  (byte) 0x14 ,  (byte) 0x28 ,  (byte) 0x50 ,  (byte) 0xa0 ,  (byte) 0x5d ,
		(byte) 0xba ,  (byte) 0x69 ,  (byte) 0xd2 ,  (byte) 0xb9 ,  (byte) 0x6f ,  (byte) 0xde ,  (byte) 0xa1 ,  (byte) 0x5f ,
		(byte) 0xbe ,  (byte) 0x61 ,  (byte) 0xc2 ,  (byte) 0x99 ,  (byte) 0x2f ,  (byte) 0x5e ,  (byte) 0xbc ,  (byte) 0x65 ,
		(byte) 0xca ,  (byte) 0x89 ,  (byte) 0x0f ,  (byte) 0x1e ,  (byte) 0x3c ,  (byte) 0x78 ,  (byte) 0xf0 ,  (byte) 0xfd ,
		(byte) 0xe7 ,  (byte) 0xd3 ,  (byte) 0xbb ,  (byte) 0x6b ,  (byte) 0xd6 ,  (byte) 0xb1 ,  (byte) 0x7f ,  (byte) 0xfe ,
		(byte) 0xe1 ,  (byte) 0xdf ,  (byte) 0xa3 ,  (byte) 0x5b ,  (byte) 0xb6 ,  (byte) 0x71 ,  (byte) 0xe2 ,  (byte) 0xd9 ,
		(byte) 0xaf ,  (byte) 0x43 ,  (byte) 0x86 ,  (byte) 0x11 ,  (byte) 0x22 ,  (byte) 0x44 ,  (byte) 0x88 ,  (byte) 0x0d ,
		(byte) 0x1a ,  (byte) 0x34 ,  (byte) 0x68 ,  (byte) 0xd0 ,  (byte) 0xbd ,  (byte) 0x67 ,  (byte) 0xce ,  (byte) 0x81 ,
		(byte) 0x1f ,  (byte) 0x3e ,  (byte) 0x7c ,  (byte) 0xf8 ,  (byte) 0xed ,  (byte) 0xc7 ,  (byte) 0x93 ,  (byte) 0x3b ,
		(byte) 0x76 ,  (byte) 0xec ,  (byte) 0xc5 ,  (byte) 0x97 ,  (byte) 0x33 ,  (byte) 0x66 ,  (byte) 0xcc ,  (byte) 0x85 ,
		(byte) 0x17 ,  (byte) 0x2e ,  (byte) 0x5c ,  (byte) 0xb8 ,  (byte) 0x6d ,  (byte) 0xda ,  (byte) 0xa9 ,  (byte) 0x4f ,
		(byte) 0x9e ,  (byte) 0x21 ,  (byte) 0x42 ,  (byte) 0x84 ,  (byte) 0x15 ,  (byte) 0x2a ,  (byte) 0x54 ,  (byte) 0xa8 ,
		(byte) 0x4d ,  (byte) 0x9a ,  (byte) 0x29 ,  (byte) 0x52 ,  (byte) 0xa4 ,  (byte) 0x55 ,  (byte) 0xaa ,  (byte) 0x49 ,
		(byte) 0x92 ,  (byte) 0x39 ,  (byte) 0x72 ,  (byte) 0xe4 ,  (byte) 0xd5 ,  (byte) 0xb7 ,  (byte) 0x73 ,  (byte) 0xe6 ,
		(byte) 0xd1 ,  (byte) 0xbf ,  (byte) 0x63 ,  (byte) 0xc6 ,  (byte) 0x91 ,  (byte) 0x3f ,  (byte) 0x7e ,  (byte) 0xfc ,
		(byte) 0xe5 ,  (byte) 0xd7 ,  (byte) 0xb3 ,  (byte) 0x7b ,  (byte) 0xf6 ,  (byte) 0xf1 ,  (byte) 0xff ,  (byte) 0xe3 ,
		(byte) 0xdb ,  (byte) 0xab ,  (byte) 0x4b ,  (byte) 0x96 ,  (byte) 0x31 ,  (byte) 0x62 ,  (byte) 0xc4 ,  (byte) 0x95 ,
		(byte) 0x37 ,  (byte) 0x6e ,  (byte) 0xdc ,  (byte) 0xa5 ,  (byte) 0x57 ,  (byte) 0xae ,  (byte) 0x41 ,  (byte) 0x82 ,
		(byte) 0x19 ,  (byte) 0x32 ,  (byte) 0x64 ,  (byte) 0xc8 ,  (byte) 0x8d ,  (byte) 0x07 ,  (byte) 0x0e ,  (byte) 0x1c ,
		(byte) 0x38 ,  (byte) 0x70 ,  (byte) 0xe0 ,  (byte) 0xdd ,  (byte) 0xa7 ,  (byte) 0x53 ,  (byte) 0xa6 ,  (byte) 0x51 ,
		(byte) 0xa2 ,  (byte) 0x59 ,  (byte) 0xb2 ,  (byte) 0x79 ,  (byte) 0xf2 ,  (byte) 0xf9 ,  (byte) 0xef ,  (byte) 0xc3 ,
		(byte) 0x9b ,  (byte) 0x2b ,  (byte) 0x56 ,  (byte) 0xac ,  (byte) 0x45 ,  (byte) 0x8a ,  (byte) 0x09 ,  (byte) 0x12 ,
		(byte) 0x24 ,  (byte) 0x48 ,  (byte) 0x90 ,  (byte) 0x3d ,  (byte) 0x7a ,  (byte) 0xf4 ,  (byte) 0xf5 ,  (byte) 0xf7 ,
		(byte) 0xf3 ,  (byte) 0xfb ,  (byte) 0xeb ,  (byte) 0xcb ,  (byte) 0x8b ,  (byte) 0x0b ,  (byte) 0x16 ,  (byte) 0x2c ,
		(byte) 0x58 ,  (byte) 0xb0 ,  (byte) 0x7d ,  (byte) 0xfa ,  (byte) 0xe9 ,  (byte) 0xcf ,  (byte) 0x83 ,  (byte) 0x1b ,
		(byte) 0x36 ,  (byte) 0x6c ,  (byte) 0xd8 ,  (byte) 0xad ,  (byte) 0x47 ,  (byte) 0x8e ,  (byte) 0x01 ,  (byte) 0x02 ,
		};
	
	// lg with exponent of primitive element as answer
	private static byte[] primitiveElmsLn = {
		(byte) 0x00 ,  (byte) 0x00 ,  (byte) 0x01 ,  (byte) 0x19 ,  (byte) 0x02 ,  (byte) 0x32 ,  (byte) 0x1a ,  (byte) 0xc6 ,
		(byte) 0x03 ,  (byte) 0xdf ,  (byte) 0x33 ,  (byte) 0xee ,  (byte) 0x1b ,  (byte) 0x68 ,  (byte) 0xc7 ,  (byte) 0x4b ,
		(byte) 0x04 ,  (byte) 0x64 ,  (byte) 0xe0 ,  (byte) 0x0e ,  (byte) 0x34 ,  (byte) 0x8d ,  (byte) 0xef ,  (byte) 0x81 ,
		(byte) 0x1c ,  (byte) 0xc1 ,  (byte) 0x69 ,  (byte) 0xf8 ,  (byte) 0xc8 ,  (byte) 0x08 ,  (byte) 0x4c ,  (byte) 0x71 ,
		(byte) 0x05 ,  (byte) 0x8a ,  (byte) 0x65 ,  (byte) 0x2f ,  (byte) 0xe1 ,  (byte) 0x24 ,  (byte) 0x0f ,  (byte) 0x21 ,
		(byte) 0x35 ,  (byte) 0x93 ,  (byte) 0x8e ,  (byte) 0xda ,  (byte) 0xf0 ,  (byte) 0x12 ,  (byte) 0x82 ,  (byte) 0x45 ,
		(byte) 0x1d ,  (byte) 0xb5 ,  (byte) 0xc2 ,  (byte) 0x7d ,  (byte) 0x6a ,  (byte) 0x27 ,  (byte) 0xf9 ,  (byte) 0xb9 ,
		(byte) 0xc9 ,  (byte) 0x9a ,  (byte) 0x09 ,  (byte) 0x78 ,  (byte) 0x4d ,  (byte) 0xe4 ,  (byte) 0x72 ,  (byte) 0xa6 ,
		(byte) 0x06 ,  (byte) 0xbf ,  (byte) 0x8b ,  (byte) 0x62 ,  (byte) 0x66 ,  (byte) 0xdd ,  (byte) 0x30 ,  (byte) 0xfd ,
		(byte) 0xe2 ,  (byte) 0x98 ,  (byte) 0x25 ,  (byte) 0xb3 ,  (byte) 0x10 ,  (byte) 0x91 ,  (byte) 0x22 ,  (byte) 0x88 ,
		(byte) 0x36 ,  (byte) 0xd0 ,  (byte) 0x94 ,  (byte) 0xce ,  (byte) 0x8f ,  (byte) 0x96 ,  (byte) 0xdb ,  (byte) 0xbd ,
		(byte) 0xf1 ,  (byte) 0xd2 ,  (byte) 0x13 ,  (byte) 0x5c ,  (byte) 0x83 ,  (byte) 0x38 ,  (byte) 0x46 ,  (byte) 0x40 ,
		(byte) 0x1e ,  (byte) 0x42 ,  (byte) 0xb6 ,  (byte) 0xa3 ,  (byte) 0xc3 ,  (byte) 0x48 ,  (byte) 0x7e ,  (byte) 0x6e ,
		(byte) 0x6b ,  (byte) 0x3a ,  (byte) 0x28 ,  (byte) 0x54 ,  (byte) 0xfa ,  (byte) 0x85 ,  (byte) 0xba ,  (byte) 0x3d ,
		(byte) 0xca ,  (byte) 0x5e ,  (byte) 0x9b ,  (byte) 0x9f ,  (byte) 0x0a ,  (byte) 0x15 ,  (byte) 0x79 ,  (byte) 0x2b ,
		(byte) 0x4e ,  (byte) 0xd4 ,  (byte) 0xe5 ,  (byte) 0xac ,  (byte) 0x73 ,  (byte) 0xf3 ,  (byte) 0xa7 ,  (byte) 0x57 ,
		(byte) 0x07 ,  (byte) 0x70 ,  (byte) 0xc0 ,  (byte) 0xf7 ,  (byte) 0x8c ,  (byte) 0x80 ,  (byte) 0x63 ,  (byte) 0x0d ,
		(byte) 0x67 ,  (byte) 0x4a ,  (byte) 0xde ,  (byte) 0xed ,  (byte) 0x31 ,  (byte) 0xc5 ,  (byte) 0xfe ,  (byte) 0x18 ,
		(byte) 0xe3 ,  (byte) 0xa5 ,  (byte) 0x99 ,  (byte) 0x77 ,  (byte) 0x26 ,  (byte) 0xb8 ,  (byte) 0xb4 ,  (byte) 0x7c ,
		(byte) 0x11 ,  (byte) 0x44 ,  (byte) 0x92 ,  (byte) 0xd9 ,  (byte) 0x23 ,  (byte) 0x20 ,  (byte) 0x89 ,  (byte) 0x2e ,
		(byte) 0x37 ,  (byte) 0x3f ,  (byte) 0xd1 ,  (byte) 0x5b ,  (byte) 0x95 ,  (byte) 0xbc ,  (byte) 0xcf ,  (byte) 0xcd ,
		(byte) 0x90 ,  (byte) 0x87 ,  (byte) 0x97 ,  (byte) 0xb2 ,  (byte) 0xdc ,  (byte) 0xfc ,  (byte) 0xbe ,  (byte) 0x61 ,
		(byte) 0xf2 ,  (byte) 0x56 ,  (byte) 0xd3 ,  (byte) 0xab ,  (byte) 0x14 ,  (byte) 0x2a ,  (byte) 0x5d ,  (byte) 0x9e ,
		(byte) 0x84 ,  (byte) 0x3c ,  (byte) 0x39 ,  (byte) 0x53 ,  (byte) 0x47 ,  (byte) 0x6d ,  (byte) 0x41 ,  (byte) 0xa2 ,
		(byte) 0x1f ,  (byte) 0x2d ,  (byte) 0x43 ,  (byte) 0xd8 ,  (byte) 0xb7 ,  (byte) 0x7b ,  (byte) 0xa4 ,  (byte) 0x76 ,
		(byte) 0xc4 ,  (byte) 0x17 ,  (byte) 0x49 ,  (byte) 0xec ,  (byte) 0x7f ,  (byte) 0x0c ,  (byte) 0x6f ,  (byte) 0xf6 ,
		(byte) 0x6c ,  (byte) 0xa1 ,  (byte) 0x3b ,  (byte) 0x52 ,  (byte) 0x29 ,  (byte) 0x9d ,  (byte) 0x55 ,  (byte) 0xaa ,
		(byte) 0xfb ,  (byte) 0x60 ,  (byte) 0x86 ,  (byte) 0xb1 ,  (byte) 0xbb ,  (byte) 0xcc ,  (byte) 0x3e ,  (byte) 0x5a ,
		(byte) 0xcb ,  (byte) 0x59 ,  (byte) 0x5f ,  (byte) 0xb0 ,  (byte) 0x9c ,  (byte) 0xa9 ,  (byte) 0xa0 ,  (byte) 0x51 ,
		(byte) 0x0b ,  (byte) 0xf5 ,  (byte) 0x16 ,  (byte) 0xeb ,  (byte) 0x7a ,  (byte) 0x75 ,  (byte) 0x2c ,  (byte) 0xd7 ,
		(byte) 0x4f ,  (byte) 0xae ,  (byte) 0xd5 ,  (byte) 0xe9 ,  (byte) 0xe6 ,  (byte) 0xe7 ,  (byte) 0xad ,  (byte) 0xe8 ,
		(byte) 0x74 ,  (byte) 0xd6 ,  (byte) 0xf4 ,  (byte) 0xea ,  (byte) 0xa8 ,  (byte) 0x50 ,  (byte) 0x58 };
	
	// L M Q H format
	// wordBlocks[version][eclevel] = codewords per block
	private static final byte[][][] wordBlocks = {{{19}, {16}, {13}, {9}},
		{{34}, {28}, {22}, {16}},
		{{55}, {44}, {17, 17}, {13, 13}},
		{{80}, {32, 32}, {24, 24}, {9, 9, 9, 9}},
		{{108}, {43, 43}, {15, 15, 16, 16}, {11, 11, 12, 12}},
		{{68, 68}, {27, 27, 27, 27}, {19, 19, 19, 19}, {15, 15, 15, 15}}};
	
	public static int hammingDist(int mynum) {
		int dist = 0;
		
		while(mynum > 0) {
			dist += mynum & 1;
			mynum >>= 1;
		}
		
		return dist;
	}
	
	/**
	 * 
	 * @param fmtInfo 15-bit format info with BCH error correction bits
	 * @return corrected 5-bit format. If there are more than three bit errors,-1 is returned.
	 */
	public static int decodeFmt(int fmtInfo) {
		int testCode;
		int testDist;
		int bestDist;
		int bestFmt;
		
		bestDist = 15;
		bestFmt = -1;
		
		// XOR unmasking
		fmtInfo ^= 0x5412;
		
		for(int i = 0; i < 32; i++) {
			
			// Encode BCH of each of the 32 possible format codes to testCode
			testCode = (i << 10) ^ chkFmtInfo(i << 10);
			
			// Test for changes
			testDist = hammingDist(fmtInfo ^ testCode);
			
			if(testDist < bestDist) {
				bestDist = testDist;
				bestFmt = i;
			}
			else if(testDist == bestDist) {
				// Two format codes can match. OMG!
				bestFmt = -1;
			}
		}
		
		return bestFmt;
	}
	
	/**
	 * 
	 * @param fmtInfo the QR Code format info
	 * @return remainder of fmtInfo divided by a generator bit field 0x537
	 */
	public static int chkFmtInfo(int fmtInfo) {
		int genPoly = 0x537;
		
		for(int i = 4; i >= 0; i--) {
			if((fmtInfo & (1 << (i + 10))) > 0) {
				fmtInfo ^= genPoly << i;
			}
		}
		
		return fmtInfo;
	}
	
	public static byte[] getBlockData(byte ecFormat, int version) {
		byte ecType;
		
		switch(ecFormat) {
		case 0x00:
			ecType = EC_M;
			break;
		case 0x01:
			ecType = EC_L;
			break;
		case 0x02:
			ecType = EC_H;
			break;
		case 0x03:
			ecType = EC_Q;
			break;
		default:
			ecType = 0x00;
		}
		
		return wordBlocks[version - 1][ecType];
	}
	
	public static String ecFmtToString(byte ecFormat) {
		switch(ecFormat) {
		case 0x00:
			return "M";
		case 0x01:
			return "L";
		case 0x02:
			return "H";
		case 0x03:
			return "Q";
		default:
			return "?";
		}
	}
}
